home *** CD-ROM | disk | FTP | other *** search
- //#define DEBUG
-
- #include "MP.h"
- #include <debug.h>
- #include <exec/lists.h>
-
- extern struct MPSem *MPSem;
-
- // LockPubScreenList
- extern struct List * __asm (*OldLockPubScreenList)(register __a6 struct Library *);
- extern void __asm (*OldUnlockPubScreenList)(register __a6 struct Library *);
-
- struct List PubScreenList;
- LONG PubListNest=0; // If Zero then Init
-
- #define PSNF_FAKE (1<<15) // Fake psn_Flags
-
- struct List *IntuitionPubScreenList;
-
- struct List * __saveds __asm NewLockPubScreenList(register __a6 struct IntuitionBase *IBase)
- {
- struct PubScreenNode *psn,*npsn;
- struct DefaultNode *dnode;
- struct List *list;
- struct Task faketask={0};
- struct Screen *fakescr;
-
- char tnamebuffer[52];
- char *tname;
-
- tname=SetupTaskName(tnamebuffer,", LPSL",50);
-
- DEBUG_CODE(
- DKP("LockPubScreenList()\n");
- )
-
- ObtainSemaphoreShared(&MPSem->ListSem);
- ObtainSemaphore(&MPSem->NodeSem);
-
- IntuitionPubScreenList=list=OldLockPubScreenList((struct Library *)IBase);
-
- /* Clone Old PS list */
-
- if(PubListNest==0)
- {
- // The OS nests calls to LockPubScreenList()/UnlockPubScreenList() only create the list when PubListNest==0
-
- /* Make PSNodes for MP's pubscreens */
-
- dnode=(struct DefaultNode *)MPSem->PromotionList[PL_PUBLICSCREENS].lh_Head;
-
- psn=(APTR)list->lh_Head;
-
- if(psn->psn_Node.ln_Succ)
- {
- while(dnode->Def_Node.ln_Succ)
- {
- if(!FindName(list,dnode->Def_Node.ln_Name))
- { /* Avoid Duplicates */
- if(npsn=AllocVec(sizeof(*npsn),MEMF_PUBLIC|MEMF_CLEAR))
- {
- if(fakescr=AllocVec(sizeof(*fakescr),MEMF_PUBLIC|MEMF_CLEAR))
- {
- /* Screen */
- fakescr->Width=dnode->Width;
- fakescr->Height=dnode->Height;
- fakescr->Title=dnode->Def_Node.ln_Name;
- fakescr->RastPort.BitMap=&fakescr->BitMap;
- fakescr->BitMap.Depth=dnode->Depth;
-
- npsn->psn_Node.ln_Name=dnode->Def_Node.ln_Name; // Safe to reference name since lists are protected till UnlockPubScreenList()
- npsn->psn_Flags=PSNF_FAKE;
- npsn->psn_SigTask=&faketask;
- npsn->psn_Screen=fakescr; // Hmmm
- AddTail(list,(struct Node *)npsn);
- }
- else
- {
- FreeVec(npsn);
- }
- }
- }
- dnode=(struct DefaultNode *)dnode->Def_Node.ln_Succ;
- }
- }
- }
- else
- {
- // nested
- }
-
-
- /*
- {
- LONG *l,q;
-
- l=0;
-
- *l=0;
- }*/
-
- PubListNest++; // Some dumb apps call LockPubScreen() inside LockPubScreenList()/UnlockPubScreenList()
-
- SetTaskName(tname);
-
- return(list);
- }
-
- void __saveds __asm NewUnlockPubScreenList(register __a6 struct IntuitionBase *IBase)
- {
- struct PubScreenNode *psn,*p2;
-
- PubListNest--;
-
-
- if(PubListNest==0)
- {
- psn=(APTR)IntuitionPubScreenList->lh_Head;
-
- while(psn->psn_Node.ln_Succ)
- {
- DKP("psn=%8lx %s\n",psn,psn->psn_Node.ln_Name);
- if(psn->psn_Flags & PSNF_FAKE)
- {
- DKP(" free psn\n");
- p2=(APTR)psn->psn_Node.ln_Succ;
- Remove((APTR)psn);
- FreeVec(psn->psn_Screen); // screen is fake to!
- FreeVec(psn);
- psn=p2;
- }
- else
- {
- psn=(APTR)psn->psn_Node.ln_Succ;
- }
- }
- }
-
- OldUnlockPubScreenList((struct Library *)IBase);
-
-
- DEBUG_CODE(
- DKP("UnlockPubScreenList()\n");
- )
-
- ReleaseSemaphore(&MPSem->NodeSem);
- ReleaseSemaphore(&MPSem->ListSem);
- }
-